package org.example.configurature;

import com.bianmaba.commons.bean.result.OperationResult;
import com.bianmaba.commons.utils.ResponseUtil;
import com.bianmaba.spring.security.basic.configuration.SecurityCorsPropertiesConfiguration;
import com.bianmaba.spring.security.basic.configuration.SecurityPropertiesConfiguration;
import com.bianmaba.spring.security.basic.handler.BianmabaAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.util.StringUtils;

@Configuration
@EnableResourceServer
public class OAuth2ResourceServer extends ResourceServerConfigurerAdapter {

    private static final String ORDER_RESOURCE_ID = "test";
    @Autowired
    protected SecurityCorsPropertiesConfiguration.CorsProperties corsProperties;
    @Autowired
    protected SecurityPropertiesConfiguration.WebSecurityProperties webSecurityProperties;
    @Autowired
    protected BianmabaAccessDeniedHandler accessDeniedHandler;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources.resourceId(ORDER_RESOURCE_ID).stateless(true);
        resources.authenticationEntryPoint((request, response, e) -> {
            OperationResult result = OperationResult.of(false, "资源请求失败，非法的访问凭证（access token）！")
                    .setStatus(401, (Integer) null, HttpStatus.valueOf(401)
                            .getReasonPhrase());
            response.setContentType(MediaType.APPLICATION_JSON_VALUE);
            response.setStatus(401);
            ResponseUtil.writeJson(response, result);
        });
        resources.accessDeniedHandler((request, response, e) -> {
            OperationResult result = OperationResult.of(false, "资源请求失败，当前用户没有取得该资源的授权，请联系管理员授权！")
                    .setStatus(403, null, HttpStatus.valueOf(403).getReasonPhrase());
            response.setStatus(403);
            ResponseUtil.writeJson(response, result);
        });
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .requestMatchers()
                .antMatchers("/management/**/*", "/product/**/*", "/order/**/*", "/oauth/logout", "/oauth/me");
        if (!StringUtils.isEmpty(webSecurityProperties.getAccessDenied().getErrorPage())) {
            accessDeniedHandler.setErrorPage(webSecurityProperties.getAccessDenied().getErrorPage());
        }
        http.exceptionHandling().accessDeniedHandler(accessDeniedHandler);
        if (corsProperties.isEnable()) {
            http.cors().and().csrf().disable();
        } else {
            if (!this.webSecurityProperties.isEnableCsrf()) {
                http.csrf().disable();
            }
        }
        http.headers().frameOptions().sameOrigin().httpStrictTransportSecurity().disable();
    }
}